package com.gaojun;

import java.awt.AWTException;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.imageio.ImageIO;

import org.bytedeco.javacpp.avcodec;
import org.bytedeco.javacpp.avutil;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameRecorder.Exception;
import org.bytedeco.javacv.Java2DFrameConverter;

import com.gaojun.tool.Constant;



/**
 * 
 * @author gaojun 本机桌面截屏和推送
 */
public class LocalScreentRecordAndPush {
	private String rtmpAddress = Constant.LIVE_PATH;
	private int audioChannel = 2;
	private long videoTS, startTime, pauseTime = 0;
	ScheduledThreadPoolExecutor screenTimer = null;
	Rectangle rectangle = null;
	FFmpegFrameRecorder recorder = null;
	Robot robot = null;
	

	/**
	 * 截屏并推送直播流
	 * 
	 * @param x
	 *            截屏界面区域的x坐标
	 * @param y
	 *            截屏界面区域的y坐标
	 * @param width
	 *            截屏界面区域的宽度
	 * @param height
	 *            截屏界面区域的高度
	 */
	public void screenRecord() {
		
		rectangle = new Rectangle(Constant.WIDTH,Constant.HEIGHT);
		recorder = new FFmpegFrameRecorder(rtmpAddress, Constant.WIDTH,Constant.HEIGHT, audioChannel);
		try {
			robot = new Robot();
		} catch (AWTException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		// 截屏
		screenTimer = new ScheduledThreadPoolExecutor(1);
		pushScreen();
	}
	
	public void screenRecord(String rtmpAddress) {
		this.rtmpAddress=rtmpAddress;
		rectangle = new Rectangle(Constant.WIDTH,Constant.HEIGHT);
		recorder = new FFmpegFrameRecorder(rtmpAddress, Constant.WIDTH,Constant.HEIGHT, audioChannel);
		try {
			robot = new Robot();
		} catch (AWTException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		// 截屏
		screenTimer = new ScheduledThreadPoolExecutor(1);
		pushScreen();
	}
	// *

	private void pushScreen() {
		// new Thread(new Runnable() {
		// @Override
		// public void run() {
		// TODO Auto-generated method stub
		try {
			recorder.setInterleaved(true);
			recorder.setOption("rtsp_transport", "tcp"); // 使用tcp的方式，不然会丢包很严重
			// 该参数用于降低延迟
			// recorder.setVideoOption("tune", "zerolatency");
			// ultrafast(终极快)提供最少的压缩（低编码器CPU）和最大的视频流大小；
			// 参考以下命令: ffmpeg -i '' -crf 30 -preset ultrafast
			recorder.setVideoOption("preset", "ultrafast");
			recorder.setVideoOption("tune", "zerolatency");
			// 提供输出流封装格式(rtmp协议只支持flv封装格式)
			recorder.setFormat("flv");
			// video的编码格式
			// AV_CODEC_ID_MPEG4
			recorder.setVideoCodec(avcodec.AV_CODEC_ID_FLV1);
			recorder.setVideoOption("crf", "23");
			// 不可变(固定)音频比特率
			recorder.setAudioOption("crf", "0");
			// 2000 kb/s, 720P视频的合理比特率范围
			// recorder.setVideoBitrate(2000000);
			// recorder.setVideoBitrate(1000000);

			recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P); // yuv420p
			recorder.setVideoQuality(0);
			// 视频帧率(保证视频质量的情况下最低25，低于25会出现闪屏
			recorder.setFrameRate(5);
			//
			recorder.start();


			screenTimer.scheduleAtFixedRate(new Runnable() {
				@Override
				public void run() {
					// long time1 = System.currentTimeMillis();
					BufferedImage screenCapture = robot.createScreenCapture(rectangle); // 截屏
					BufferedImage videoImg = new BufferedImage(screenCapture.getWidth(), screenCapture.getHeight(),
							BufferedImage.TYPE_3BYTE_BGR); // 声明一个BufferedImage用重绘截图
					Graphics2D videoGraphics = videoImg.createGraphics();// 创建videoImg的Graphics2D
					videoGraphics.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
					videoGraphics.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
							RenderingHints.VALUE_COLOR_RENDER_SPEED);
					videoGraphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
					videoGraphics.drawImage(screenCapture, 0, 0, null); // 重绘截图
					if (Constant.WATER_TYPE==0) {
						videoGraphics.setFont(new Font(Constant.FONT_FAMILY, Font.PLAIN, (int)Constant.FONT_SIZE));
						float r=(float)Constant.color.getRed();
						float g=(float)Constant.color.getGreen();
						float b=(float)Constant.color.getBlue();
						videoGraphics.setColor(new Color(r, g, b));
						videoGraphics.drawString(Constant.WATER_MARK, 30, (int)Constant.FONT_SIZE);
					}
				
					if (Constant.WATER_TYPE==1) {
						try {
							BufferedImage waterimg=ImageIO.read(new File(Constant.WATER_MARK));
							videoGraphics.drawImage(waterimg, 10, 10, null);
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						
					}
					Java2DFrameConverter java2dConverter = new Java2DFrameConverter();
					Frame frame = java2dConverter.convert(videoImg);
					try {
						videoTS = 1000L
								* (System.currentTimeMillis() - startTime - (System.currentTimeMillis() - pauseTime));
						// 检查偏移量
						if (videoTS > recorder.getTimestamp()) {
							recorder.setTimestamp(videoTS);
						}
						//
						// long time2 = System.currentTimeMillis();
						// System.out.println("耗时："+(time2-time1));

						recorder.record(frame); // 录制视频
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					// 释放资源
					videoGraphics.dispose();
					videoGraphics = null;
					videoImg.flush();
					videoImg = null;
					java2dConverter = null;
					screenCapture.flush();
					screenCapture = null;

				}
			}, (int) (1000 / 5), (int) (1000 / 5), TimeUnit.MILLISECONDS);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			if (screenTimer != null) {
				screenTimer.shutdown();
				screenTimer = null;
			}
			if (recorder != null) {
				try {
					recorder.close();
				} catch (Exception ex) {
					// TODO Auto-generated catch block
					ex.printStackTrace();
				}
			}
		}

		// }
		// }).start();

	}

	public void stop() {
		if (screenTimer != null) {
			screenTimer.shutdown();
			screenTimer = null;
		}
		if (recorder != null) {
			try {
				recorder.close();
			} catch (Exception ex) {
				// TODO Auto-generated catch block
				ex.printStackTrace();
			}
		}
	}

}
